#!/bin/bash

# 端口管理脚本 - 用于检测和释放8091端口

PORT=8091
ECHO="echo"

# 检测操作系统类型，调整命令格式
if [[ "$(uname)" == "Darwin" ]]; then
    # macOS系统
    NETSTAT_CMD="netstat -anv | grep $PORT"
    LSOF_CMD="lsof -i :$PORT"
    KILL_CMD="kill"
    KILL_9_CMD="kill -9"
else
    # Linux系统
    NETSTAT_CMD="netstat -tulpn | grep $PORT"
    LSOF_CMD="lsof -i :$PORT"
    KILL_CMD="kill"
    KILL_9_CMD="kill -9"
fi

# 检测端口占用情况
detect_port_usage() {
    $ECHO "正在检测端口 $PORT 的使用情况..."
    local has_permission_issue=false
    
    # 使用netstat检查
    $ECHO "\n方法一: 使用netstat检查端口占用"
    if command -v netstat &> /dev/null; then
        local netstat_output=$(eval $NETSTAT_CMD 2>&1)
        if [[ -n "$netstat_output" ]]; then
            echo "$netstat_output"
        else
            $ECHO "未检测到端口占用（netstat）或无足够权限查看所有进程"
            # 检查是否包含权限错误提示
            if eval $NETSTAT_CMD 2>&1 | grep -i "permission" &> /dev/null; then
                has_permission_issue=true
            fi
        fi
    else
        $ECHO "警告: 未找到netstat命令，请确保已安装net-tools包"
    fi
    
    # 使用lsof检查
    $ECHO "\n方法二: 使用lsof检查端口占用"
    if command -v lsof &> /dev/null; then
        local lsof_output=$(eval $LSOF_CMD 2>&1)
        if [[ -n "$lsof_output" ]]; then
            echo "$lsof_output"
        else
            $ECHO "未检测到端口占用（lsof）或无足够权限查看所有进程"
            # 检查是否包含权限错误提示
            if eval $LSOF_CMD 2>&1 | grep -i "permission" &> /dev/null; then
                has_permission_issue=true
            fi
        fi
    else
        $ECHO "警告: 未找到lsof命令，请确保已安装lsof包"
    fi
    
    # 权限问题提示
    if [[ "$has_permission_issue" == "true" ]]; then
        $ECHO "\n🔒 权限提示: 检测到权限限制，可能无法查看所有占用端口的进程"
        $ECHO "🔒 建议使用 sudo 运行此脚本以获取完整权限"
    fi
    
    # 获取占用端口的进程ID列表（忽略权限错误）
    local pids_found=false
    if command -v lsof &> /dev/null; then
        PIDS=$(lsof -t -i:$PORT 2>/dev/null)
        if [[ -n "$PIDS" ]]; then
            $ECHO "\n检测到占用端口 $PORT 的进程ID: $PIDS"
            pids_found=true
            return 0  # 端口被占用
        fi
    fi
    
    # 如果lsof不可用，尝试使用netstat和awk获取PID
    if [[ "$pids_found" == "false" ]] && command -v netstat &> /dev/null && command -v awk &> /dev/null; then
        if [[ "$(uname)" == "Darwin" ]]; then
            # macOS的netstat输出格式不同
            PIDS=$(netstat -anv 2>/dev/null | grep ":$PORT " | awk '{print $9}')
        else
            PIDS=$(netstat -tulpn 2>/dev/null | grep ":$PORT " | grep -oP 'pid=\K\d+' || echo "")
        fi
        
        if [[ -n "$PIDS" && "$PIDS" != "*" ]]; then
            $ECHO "\n检测到占用端口 $PORT 的进程ID: $PIDS"
            return 0  # 端口被占用
        fi
    fi
    
    $ECHO "\n端口 $PORT 当前未被占用，或无足够权限查看所有占用进程"
    return 1  # 端口未被占用或无权限
}

# 释放端口（终止占用进程）
release_port() {
    local force_mode=$1
    local pids_to_kill
    local permission_warning_shown=false
    
    # 获取占用端口的进程ID（忽略权限错误）
    if command -v lsof &> /dev/null; then
        pids_to_kill=$(lsof -t -i:$PORT 2>/dev/null)
    else
        # 备选方法
        if [[ "$(uname)" == "Darwin" ]]; then
            pids_to_kill=$(netstat -anv 2>/dev/null | grep ":$PORT " | awk '{print $9}')
        else
            pids_to_kill=$(netstat -tulpn 2>/dev/null | grep ":$PORT " | grep -oP 'pid=\K\d+' || echo "")
        fi
    fi
    
    if [[ -z "$pids_to_kill" || "$pids_to_kill" == "*" ]]; then
        # 检查是否有可能是权限问题导致无法获取PID
        if [[ $EUID -ne 0 ]]; then
            $ECHO "端口 $PORT 未检测到占用，或可能由于权限限制无法查看所有进程"
            $ECHO "建议: 使用 sudo 运行此脚本以获取完整权限查看所有进程"
        else
            $ECHO "端口 $PORT 未被占用，无需释放"
        fi
        return 1
    fi
    
    $ECHO "正在终止占用端口 $PORT 的进程: $pids_to_kill"
    
    # 根据模式选择终止命令
    if [[ "$force_mode" == "true" ]]; then
        $ECHO "使用强制终止模式 (-9)"
        for pid in $pids_to_kill; do
            $ECHO "强制终止进程 $pid..."
            $KILL_9_CMD "$pid" 2>/dev/null
            if [[ $? -eq 0 ]]; then
                $ECHO "✅ 进程 $pid 已强制终止"
            else
                $ECHO "❌ 错误: 无法终止进程 $pid"
                $ECHO "   可能原因: 权限不足或进程已不存在"
                if [[ $EUID -ne 0 && "$permission_warning_shown" == "false" ]]; then
                    $ECHO "   建议: 使用 sudo 运行此脚本以获取终止其他用户进程的权限"
                    permission_warning_shown=true
                fi
            fi
        done
    else
        $ECHO "使用正常终止模式"
        for pid in $pids_to_kill; do
            $ECHO "尝试正常终止进程 $pid..."
            $KILL_CMD "$pid" 2>/dev/null
            if [[ $? -eq 0 ]]; then
                $ECHO "✅ 进程 $pid 已发送终止信号，等待优雅退出..."
                # 等待1秒给进程优雅退出的时间
                sleep 1
                # 检查进程是否还在运行
                if ps -p "$pid" > /dev/null 2>&1; then
                    $ECHO "进程 $pid 未退出，尝试强制终止..."
                    $KILL_9_CMD "$pid" 2>/dev/null
                    if [[ $? -eq 0 ]]; then
                        $ECHO "✅ 进程 $pid 已强制终止"
                    else
                        $ECHO "❌ 错误: 无法强制终止进程 $pid"
                        if [[ $EUID -ne 0 && "$permission_warning_shown" == "false" ]]; then
                            $ECHO "   建议: 使用 sudo 运行此脚本以获取终止其他用户进程的权限"
                            permission_warning_shown=true
                        fi
                    fi
                else
                    $ECHO "✅ 进程 $pid 已成功退出"
                fi
            else
                $ECHO "❌ 错误: 无法向进程 $pid 发送终止信号"
                if [[ $EUID -ne 0 && "$permission_warning_shown" == "false" ]]; then
                    $ECHO "   建议: 使用 sudo 运行此脚本以获取终止其他用户进程的权限"
                    permission_warning_shown=true
                fi
            fi
        done
    fi
    
    # 验证端口是否已释放
    sleep 1
    $ECHO "\n验证端口释放结果..."
    detect_port_usage
    if [[ $? -eq 1 ]]; then
        $ECHO "\n✅ 端口 $PORT 已成功释放！"
        return 0
    else
        $ECHO "\n⚠️  警告: 端口 $PORT 可能仍被占用"
        if [[ $EUID -ne 0 ]]; then
            $ECHO "   可能原因: 权限不足，无法查看或终止所有占用进程"
            $ECHO "   建议: 使用 sudo 运行此脚本以获取完整权限"
            $ECHO "   示例: sudo ./port_management.sh --release --force"
        else
            $ECHO "   建议: 尝试使用强制模式重新运行此脚本"
            $ECHO "   示例: ./port_management.sh --release --force"
        fi
        return 1
    fi
}

# 检查端口可用性并准备启动服务
prepare_port_for_service() {
    $ECHO "🔧 准备端口 $PORT 用于服务启动..."
    
    # 权限提示
    if [[ $EUID -ne 0 ]]; then
        $ECHO "⚠️  注意: 您当前不是以root用户运行，可能无法查看或终止所有占用进程"
        $ECHO "⚠️  如果端口仍被占用，建议使用 sudo 运行此脚本"
    fi
    
    # 检测端口占用
    detect_port_usage
    if [[ $? -eq 0 ]]; then
        $ECHO "\n🚨 端口 $PORT 已被占用，需要释放后才能启动服务"
        $ECHO "🔄 正在尝试释放端口..."
        release_port "false"  # 先尝试正常终止
        
        # 如果正常终止失败，尝试强制终止
        detect_port_usage
        if [[ $? -eq 0 ]]; then
            $ECHO "\n⚠️  正常终止失败，尝试强制终止占用进程..."
            release_port "true"
        fi
    fi
    
    # 最终检查
    detect_port_usage
    if [[ $? -eq 1 ]]; then
        $ECHO "\n✅ 端口 $PORT 现已可用，可以启动服务"
        return 0
    else
        $ECHO "\n❌ 错误: 无法完全释放端口 $PORT"
        if [[ $EUID -ne 0 ]]; then
            $ECHO "   可能原因: 权限不足，无法查看或终止所有占用进程"
            $ECHO "   解决方法: 使用 sudo 运行此脚本"
            $ECHO "   示例: sudo ./port_management.sh --prepare"
        else
            $ECHO "   解决方法1: 手动检查并终止占用进程"
            $ECHO "   示例: sudo lsof -i :$PORT  # 查看占用进程"
            $ECHO "        sudo kill -9 进程ID  # 终止进程"
            $ECHO "   解决方法2: 重启网络服务（谨慎使用）"
        fi
        return 1
    fi
}

# 显示帮助信息
show_help() {
    $ECHO "端口管理脚本 v1.0 - 用于管理8091端口资源"
    $ECHO ""
    $ECHO "用法: $0 [选项]"
    $ECHO ""
    $ECHO "选项:"
    $ECHO "  -d, --detect    检测端口占用情况"
    $ECHO "  -r, --release   释放端口（终止占用进程）"
    $ECHO "  -f, --force     强制释放端口（与 -r 一起使用）"
    $ECHO "  -p, --prepare   准备端口用于服务启动（检测并释放）"
    $ECHO "  -h, --help      显示此帮助信息"
    $ECHO ""
    $ECHO "示例:"
    $ECHO "  $0 -d         # 检测8091端口占用情况"
    $ECHO "  $0 -r         # 释放8091端口"
    $ECHO "  $0 -r -f      # 强制释放8091端口"
    $ECHO "  $0 -p         # 准备8091端口用于服务启动"
}

# 主函数
main() {
    # 检查是否有足够权限
    if [[ $EUID -ne 0 ]]; then
        $ECHO "⚠️  权限提示: 您当前不是以root用户运行此脚本"
        $ECHO "⚠️  您将只能查看和管理当前用户拥有的进程"
        $ECHO "⚠️  要查看所有进程（包括其他用户的进程），请使用 sudo 运行此脚本"
        $ECHO "例如: sudo ./port_management.sh --detect"
        $ECHO ""
    fi
    
    # 处理命令行参数
    if [[ $# -eq 0 ]]; then
        # 默认行为：检测端口状态
        detect_port_usage
    else
        local release_mode="false"
        local force_mode="false"
        
        while [[ $# -gt 0 ]]; do
            case "$1" in
                -d|--detect)
                    detect_port_usage
                    exit 0
                    ;;
                -r|--release)
                    release_mode="true"
                    ;;
                -f|--force)
                    force_mode="true"
                    ;;
                -p|--prepare)
                    prepare_port_for_service
                    exit $?
                    ;;
                -h|--help)
                    show_help
                    exit 0
                    ;;
                *)
                    $ECHO "错误: 未知选项 '$1'"
                    show_help
                    exit 1
                    ;;
            esac
            shift
        done
        
        # 处理释放端口的请求
        if [[ "$release_mode" == "true" ]]; then
            release_port "$force_mode"
        fi
    fi
}

# 执行主函数
main "$@"